package edu.objects;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Random;

import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

import com.google.appengine.api.datastore.Key;

@PersistenceCapable
public class LetterBag {
	
	@Persistent(serialized = "true")
	private HashMap<String,Integer> _pointValues;

	@Persistent(serialized = "true")
	private HashMap<String,Integer> _available;
	
	private Random rand;
	
	@PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Key key;
	
	
	public void setKey(Key key) {
        this.key = key;
    }

	public LetterBag() {
		rand = new Random();
		
		_pointValues = new HashMap<String,Integer>();
		_pointValues.put("A", 1);
		_pointValues.put("B", 3);
		_pointValues.put("C", 3);
		_pointValues.put("D", 2);
		_pointValues.put("E", 1);
		_pointValues.put("F", 4);
		_pointValues.put("G", 2);
		_pointValues.put("H", 4);
		_pointValues.put("I", 1);
		_pointValues.put("J", 8);
		_pointValues.put("K", 5);
		_pointValues.put("L", 1);
		_pointValues.put("M", 3);
		_pointValues.put("N", 1);
		_pointValues.put("O", 1);
		_pointValues.put("P", 3);
		_pointValues.put("Q", 10);
		_pointValues.put("R", 1);
		_pointValues.put("S", 1);
		_pointValues.put("T", 1);
		_pointValues.put("U", 1);
		_pointValues.put("V", 4);
		_pointValues.put("W", 4);
		_pointValues.put("X", 8);
		_pointValues.put("Y", 4);
		_pointValues.put("Z", 3);
		//TODO: point values for all.
		
		_available = new HashMap<String,Integer>();
		_available.put("A",9);
		_available.put("B",2);
		_available.put("C",2);
		_available.put("D",4);
		_available.put("E",12);
		_available.put("F",2);
		_available.put("G",3);
		_available.put("H",2);
		_available.put("I",9);
		_available.put("J",1);
		_available.put("K",1);
		_available.put("L",4);
		_available.put("M",2);
		_available.put("N",6);
		_available.put("O",8);
		_available.put("P",2);
		_available.put("Q",1);
		_available.put("R",6);
		_available.put("S",4);
		_available.put("T",6);
		_available.put("U",4);
		_available.put("V",2);
		_available.put("W",2);
		_available.put("X",1);
		_available.put("Y",2);
		_available.put("Z",1);
		_available.put("_",2);
	}
	
	public char[] grabLetters(int count) {
		char[] grabbed = new char[count];
		for (int i=0; i<count; i++) {
			boolean placed = false;
			int nthLetterIndex = rand.nextInt(getLettersRemaining());
			//Get the n-index of all letters:
			Iterator<String> iterator = _available.keySet().iterator();
			while (iterator.hasNext() && !placed) {
				String letter = iterator.next();
				if (nthLetterIndex < _available.get(letter)) {
					//index is in this range, take one of these.
					grabbed[i] = letter.charAt(0);
					_available.put(letter,_available.get(letter)-1);
					placed = true;
				} else {
					nthLetterIndex -= _available.get(letter);
				}
			}
		}
		return grabbed;
	}
	
	public int getLettersRemaining() {
		Collection<Integer> letters = _available.values();
		int sum=0;
		Iterator<Integer> iterator = letters.iterator();
		while (iterator.hasNext()) {
			sum += iterator.next();
		}
		return sum;
	}
	
	public int getPointValue(char ltr) {
		String letter = Character.toString(Character.toUpperCase(ltr));
		int value = 0;
		if (_pointValues.containsKey(letter)) {
			value = _pointValues.get(letter);
		}
		return value;
	}
	
	public char[] tradeLetters(char[] toTrade) {
		for (int i=0; i<toTrade.length; i++) {
			String letter = (String.valueOf(toTrade[i])).toUpperCase();
			_available.put(letter, _available.get(letter)+1);
		}
		//Added to bag, now take.
		return grabLetters(toTrade.length);
	}
	
	public boolean isEmpty()
	{
		return getLettersRemaining() == 0;
	}
	
}